package top.lixb.libcommon.utils;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;

/**
 * author：agxxxx on 2017/3/22 15:51
 * email：agxxxx@126.com
 * jianShu: http://www.jianshu.com/u/c1a3c4c943e5
 * blog: http://blog.csdn.net/zuiaisha1
 * github: https://github.com/agxxxx
 * Created by Administrator on 2017/3/22.
 */

public class BitmapUtil {
	public static final String TAG = "BitmapUtil";
	public static String Bitmap2StrByBase64(Bitmap bit) {
		if (bit != null) {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			bit.compress(Bitmap.CompressFormat.JPEG, 60, bos);//参数100表示不压缩
			byte[] bytes = bos.toByteArray();
			String avatar     = Base64.encodeToString(bytes, Base64.NO_WRAP);
			return avatar;
		} else {
			return "";
		}
	}
	/**
	 * 合并两个bitmap
	 * @param backBitmap
	 * @param frontBitmap
	 * @return
	 */
	public static Bitmap mergeBitmap(Bitmap backBitmap, Bitmap frontBitmap) {

		if (backBitmap == null || backBitmap.isRecycled()
				|| frontBitmap == null || frontBitmap.isRecycled()) {
			Log.e(TAG, "backBitmap=" + backBitmap + ";frontBitmap=" + frontBitmap);
			return null;
		}
		Bitmap bitmap = backBitmap.copy(Config.ARGB_8888, true);
		Canvas canvas = new Canvas(bitmap);
		Rect baseRect  = new Rect(0, 0, backBitmap.getWidth(), backBitmap.getHeight());
		Rect frontRect = new Rect(0, 0, frontBitmap.getWidth(), frontBitmap.getHeight());
		canvas.drawBitmap(frontBitmap, frontRect, baseRect, null);
		return bitmap;
	}
	/**
	 * drawable transfer to bitmap
	 * @param drawable
	 * @return
	 */
	public static Bitmap drawableToBitmap2(Drawable drawable) {

		Bitmap bitmap = Bitmap.createBitmap(

		drawable.getIntrinsicWidth(),
		drawable.getIntrinsicHeight(),

		drawable.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888 : Config.RGB_565);

		Canvas canvas = new Canvas(bitmap);

		// canvas.setBitmap(bitmap);

		drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
				drawable.getIntrinsicHeight());
		drawable.draw(canvas);

		return bitmap;

	}
	
	public static Bitmap drawableToBitmap(Drawable drawable) {
		// 取 drawable 的长宽
		int w = drawable.getIntrinsicWidth();
		int h = drawable.getIntrinsicHeight();

		// 取 drawable 的颜色格式
		Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888
				: Config.RGB_565;
		// 建立对应 bitmap
		Bitmap bitmap = Bitmap.createBitmap(w, h, config);
		// 建立对应 bitmap 的画布
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, w, h);
		// 把 drawable 内容画到画布中
		drawable.draw(canvas);
		return bitmap;
	}

	// 通过传入位图,新的宽.高比进行位图的缩放操作
	public static Drawable resizeImage(Bitmap bitmap, int w, int h) {

		// load the origial Bitmap
		Bitmap BitmapOrg = bitmap;

		int width = BitmapOrg.getWidth();
		int height = BitmapOrg.getHeight();
		int newWidth = w;
		int newHeight = h;

		// calculate the scale
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		// create a matrix for the manipulation
		Matrix matrix = new Matrix();
		// resize the Bitmap
		matrix.postScale(scaleWidth, scaleHeight);
		// if you want to rotate the Bitmap
		// matrix.postRotate(45);

		// recreate the new Bitmap
		Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
				height, matrix, true);

		// make a Drawable from Bitmap to allow to set the Bitmap
		// to the ImageView, ImageButton or what ever
		return new BitmapDrawable(resizedBitmap);

	}
	
	public static Bitmap resizeBitmap(Bitmap bitmap, int w, int h) {

		// load the origial Bitmap
		Bitmap BitmapOrg = bitmap;

		int width = BitmapOrg.getWidth();
		int height = BitmapOrg.getHeight();
		int newWidth = w;
		int newHeight = h;

		// calculate the scale
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		// create a matrix for the manipulation
		Matrix matrix = new Matrix();
		// resize the Bitmap
		matrix.postScale(scaleWidth, scaleHeight);
		// if you want to rotate the Bitmap
		// matrix.postRotate(45);

		// recreate the new Bitmap
		Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,
				height, matrix, true);

		return resizedBitmap;
	}

	public static Drawable bitmapToDrawable(Bitmap bitmap) {
		Drawable drawable = new BitmapDrawable(bitmap);
		return drawable;
	}
	
	/**
	 * 保存图片
	 * 
	 * @param bitmap
	 *           要保持的图片
	 * @param filePath
	 *           保存路径
	 * @param name
	 *           保存文件名
	 * @return
	 */
	public static String SaveBitmap(Bitmap bitmap, String filePath, String name) {
		File file = new File(filePath);
		String path = null;
		if (!file.exists()) {
			file.mkdirs();
		}
		try {
			path = file.getPath() + "/" + name;
			FileOutputStream fileOutputStream = new FileOutputStream(path);

			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
			fileOutputStream.flush();
			fileOutputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return path;
	}
	
	public static String SaveBitmap(Bitmap bitmap, int compressRatio, String filePath, String name) {
		
		Log.e("bitmapUtil", "org width:" + bitmap.getWidth()  + "org Height:" + bitmap.getHeight());
		
		File file = new File(filePath);
		String path = null;
		if (!file.exists()) {
			file.mkdirs();
		}
		try {
			path = file.getPath() + "/" + name;
			FileOutputStream fileOutputStream = new FileOutputStream(path);

			if(compressRatio > 100) {
				compressRatio = 100;
			}
			if(compressRatio < 1) {
				compressRatio = 1;
			}
			bitmap.compress(Bitmap.CompressFormat.JPEG, compressRatio, fileOutputStream);
			fileOutputStream.flush();
			fileOutputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return path;
	}
	
	/**
	 * 从sd卡读取图片
	 * 
	 * @param path
	 * @return
	 */
	public static Bitmap readBitMap(String path) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inPreferredConfig = Config.ARGB_8888;
		Bitmap bm = BitmapFactory.decodeFile(path, options);
		return bm;
	}
	
    /** 
     * compute Sample Size 
     *  
     * @param options 
     * @param minSideLength 
     * @param maxNumOfPixels 
     * @return 
     */  
    public static int computeSampleSize(BitmapFactory.Options options,  
            int minSideLength, int maxNumOfPixels) {  
        int initialSize = computeInitialSampleSize(options, minSideLength,  
                maxNumOfPixels);  
      
        int roundedSize;  
        if (initialSize <= 8) {  
            roundedSize = 1;  
            while (roundedSize < initialSize) {  
                roundedSize <<= 1;  
            }  
        } else {  
            roundedSize = (initialSize + 7) / 8 * 8;  
        }  
        return roundedSize;
    }  
      
    /** 
     * compute Initial Sample Size 
     * @param options
     * @param minSideLength 
     * @param maxNumOfPixels 
     * @return 
     */  
    private static int computeInitialSampleSize(BitmapFactory.Options options,  
            int minSideLength, int maxNumOfPixels) {  
        double w = options.outWidth;  
        double h = options.outHeight;
        // 上下限范围
        int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math  
                .sqrt(w * h / maxNumOfPixels));  
        int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(  
                Math.floor(w / minSideLength), Math.floor(h / minSideLength));  
      
        if (upperBound < lowerBound) {  
            // go_back the larger one when there is no overlapping zone.
            return lowerBound;  
        }  
      
        if ((maxNumOfPixels == -1) && (minSideLength == -1)) {  
            return 1;  
        } else if (minSideLength == -1) {  
            return lowerBound;  
        } else {  
            return upperBound;  
        }  
    }  
    
    public static Drawable resizeDrawable(Drawable drawable, int w, int h) {
          int width = drawable.getIntrinsicWidth();
          int height= drawable.getIntrinsicHeight();
          Bitmap oldbmp = drawableToBitmap(drawable); 
          Matrix matrix = new Matrix();  
          float scaleWidth = ((float)w / width);   
          float scaleHeight = ((float)h / height);
          matrix.postScale(scaleWidth, scaleHeight); 
          Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);  
          return new BitmapDrawable(newbmp).getCurrent();
    }


	/**
	 * 加载大图
	 * @param imgPath
	 * @param rqWidth
	 * @param rqHeight
	 * @return
	 */
	public static Bitmap getSampleBitmap(String imgPath,int rqWidth,int rqHeight) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = false;
//          options.inJustDecodeBounds = true;//为true的时候不会真正加载图片，而是得到图片的宽高信息。
		//采样率
		options.inSampleSize = computeSampleSize(options,rqWidth,rqHeight);
		Bitmap bitmap = BitmapFactory.decodeFile(imgPath, options);
		return bitmap;
	}

	/**
	 * 获取压缩后图片的字节码
	 *
	 * @return
	 */
	public static String imgPath2Base64(String sourceImgPath) {
		// 数值越高，图片像素越低
		int inSampleSize = 6;
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = false;
//          options.inJustDecodeBounds = true;//为true的时候不会真正加载图片，而是得到图片的宽高信息。
		//采样率
		options.inSampleSize = inSampleSize;
		Bitmap bitmap = BitmapFactory.decodeFile(sourceImgPath, options);
		return Bitmap2StrByBase64(bitmap);
	}
}
